#ifndef __SERVER_H_
#define __SERVER_H_

/**
 * @file server.h
 * @brief Serveur de fichier.
 * @author Florian.B
 * @version 0.5
 * @date 4 avril 2012
 * @revision 4 octobre 2012
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#ifdef _WIN32
# include <winsock2.h>
# include <ws2tcpip.h>
# include <process.h>
# include <Windows.h>
#else
# include "sys/socket.h"
# include <unistd.h>
# include <netdb.h>
#endif
#include <pthread.h>
#include "mutexsocketlist.h"

/**
 * @struct Server
 * @brief Objet Server
 *
 * Server est un petit objet qui permet de réaliser un serveur de fichier. Il
 * possède des threads de services qui pourront répondres aux différents
 * clients.
 */
typedef struct _Server
{
  char *port; /*!< Le numéro du port de connexion. */
  int socket; /*!< La socket d'écoute de nouveau client. */
  int nbThread; /*!< Le nombre de threads de service. */
  int nbSocketAttente; /*!< Le nombre maximum de client connecté. */
  pthread_t threadServer; /*!< Le thread qui execute le server en background. */
  pthread_t threadNewConnection; /*!< Le thread qui gère les nouvelles
    connexions. */
  pthread_t *tabThread; /*!< Sauvegarde les threads de service. */
  MutexSocketList mutexSocketList; /*!< MutexSocketList pour gérer les sockets
    des clients. */
  int pipeProgrammeServer[2]; /*!< Socket pour l’arrêt des threads de
    sevices. */
  int pipeServerNewConnection[2]; /*!< Socket pour la gestion des clients. */
  List lFolder; /*!< Répertoire de partage. */
}Server;

/**
 * @enum ServerReturn
 * @brief Constantes de retour.
 *
 * ServerReturn est une série de constantes prédéfinies pour diverses futures
 * fonctions de l'objet Server.
 */
typedef enum
  {
    SERVER_SUCCESS, /*!< Succès. */
    SERVER_ERR, /*!< Erreur. */
    SERVER_QUIT, /*!< Le server se ferme. */
    SERVER_SOCKET, /*!< Réception sur un socket d’un client. */
    SERVER_CLIENT_QUIT, /*!< Un client veut terminer la transaction. */
    SERVER_CON_ERR, /*!< Problème de connexion avec le client. */
    SERVER_ACTIVE, /*!< Le serveur est activé. */
    SERVER_CLOSE, /*!< Le serveur est éteint. */
    SERVER_NB_RET /*!< Nombre total de constantes de retour. */
  }ServerReturn;

/**
 * @fn void server(const int nbThread, const char *port,
 * const int nbSocketAttente)
 * @brief crée le serveur cette fonction se termine lors de la fermeture du
 * serveur.
 *
 * @param nbThread Le nombre de thread de service.
 * @param port Le port de connexion du programme.
 * @param nbSocketAttente Le nombre de socket en attente dans la file d'attente.
 */
void prepare_Server(Server *server, const int nbThread, const char *port,
                    const List *lFolder, const int nbSocketAttente);

void destroy_Server(Server *server);

/**
 * @fn ServerReturn start_Server(Server *server)
 * @brief Active le serveur.
 *
 * @param Le serveur à activer.
 * @return SERVER_ACTIVE si l'activation à fonctionner et SERVER_ERR sinon.
 */
ServerReturn start_Server(Server *server);

/**
 * @fn ServerReturn close_Server(Server *server)
 * @brief Désactive le serveur.
 *
 * @param Le serveur à désactiver.
 * @return SERVER_CLOSE si la désactivation à fonctionner.
 */
ServerReturn close_Server(Server *server);

/**
  * @fn const char *getPort_Server(Server *server)
  * @brief Retourne le port du serveur.
  *
  * @param Le serveur.
  * @return Le numéro du port.
  */
const char *getPort_Server(Server *server);

/**
  * @fn void setPort_Server(Server *server, const char *port)
  * @brief Change le port du serveur.
  * @warning Le serveur doit être détruit.
  *
  * @param server Le serveur.
  * @param port Le numéro du port.
  */
void setPort_Server(Server *server, const char *port);

/**
  * @fn const int getThread_Server(Server *server)
  * @brief Retourne le thread du serveur.
  *
  * @param Le serveur.
  * @return Le numéro du thread.
  */
int getThread_Server(Server *server);

/**
  * @fn void setThread_Server(Server *server, const int nbThread)
  * @brief Change le nombre de thread du serveur.
  * @warning Le serveur doit être détruit.
  *
  * @param server Le serveur.
  * @param thread Le nombre de thread.
  */
void setThread_Server(Server *server, const int nbThread);

#endif
